﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FireStarterModeller.BO;
using FireStarterModeller.UI.Class;
using Habanero.Base;
using Habanero.Faces.Win;

namespace FireStarterModeller.UI
{
    public class SolutionValidator
    {
        private readonly IFireStarterFormsController _formsController;
        private readonly DMSolution _solution;
        private IList<IBOError> _errors;
        private ShowErrors _showErrors;

        public SolutionValidator(DMSolution solution, IFireStarterFormsController formsController)
        {
            if (solution == null) throw new ArgumentNullException("solution");
            if (formsController == null) throw new ArgumentNullException("formsController");
            _formsController = formsController;
            _solution = solution;
        }


        public IList<IBOError> ValidateSolution()
        {
            try
            {
                if (_solution == null) return new List<IBOError>();
                Cursor.Current = Cursors.WaitCursor;
                _errors = _solution.Validate();
                if (_errors.Count > 0)
                {
                    Cursor.Current = Cursors.Default;
                    return _errors;
                }
            }
            catch (Exception ex)
            {
                Cursor.Current = Cursors.Default;
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
            _errors = new List<IBOError>();
            return _errors;
        }

//        public void ShowErrorsForSolution(IList<IBOError> errors)
//        {
//            Cursor.Current = Cursors.Default;
//            string solutionToString = _solution.ToString();
//            string headingText = "You cannot generate for '" + solutionToString + "' because the following rules are broken.";
//            string descriptionText = "Please fix these prior to generating for '" + solutionToString + "'";
//            IFormHabanero form = _formsController.CreateShowErrorsForm(errors, "Errors in Solution", headingText, descriptionText);
//            form.Show();
//        }        
/*        
        public IFormHabanero ShowErrorsForSolution(IList<IBOError> errors)
        {
            Cursor.Current = Cursors.Default;
            string solutionToString = _solution.ToString();
            string headingText = "You cannot generate for '" + solutionToString + "' because the following rules are broken.";
            string descriptionText = "Please fix these prior to generating for '" + solutionToString + "'";
            IFormHabanero form = _formsController.CreateShowErrorsForm(errors, "Errors in Solution", headingText, descriptionText);
            return form;
        }*/

        public bool CheckSolutionIsValid()
        {
            if (HasErrors(out _errors))
            {
                FormWin formWin = ((FormWin)_formsController.MainProgramForm);
                if (formWin.OwnedForms.Count() > 0)
                {
                    formWin.OwnedForms[0].Activate();
                }
                else
                {
                    _showErrors = new ShowErrors(_solution, _formsController.ControlFactory);
                    _showErrors.Show(formWin);
                }
                return false;
            }
            return true;
        }

        public bool HasErrors(out IList<IBOError> errors)
        {
            errors = ValidateSolution();
            if (errors.Count == 0) return false;
            if (new List<IBOError>(errors).TrueForAll(t => t.Level == ErrorLevel.Suggestion)) return false;
            Cursor.Current = Cursors.Default;
            return true;
        }

        public static bool HasWarningsOnly(IEnumerable<IBOError> errors)
        {
            return new List<IBOError>(errors).TrueForAll(t => t.Level == ErrorLevel.Warning);
        }

        public static bool HasErrorsOnly(IEnumerable<IBOError> errors)
        {
            return new List<IBOError>(errors).TrueForAll(t => t.Level == ErrorLevel.Error);
        }

        public bool HasErrorsOnly()
        {
            if (_errors == null) _errors = ValidateSolution();
            return HasErrorsOnly(_errors);
        }

        public bool HasWarningsOnly()
        {
            if (_errors == null) _errors = ValidateSolution();
            return HasWarningsOnly(_errors);
        }
    }
}
